package cn.gailvlun.gll.chatlib;

import android.util.Log;

import com.blankj.utilcode.util.FileUtils;
import com.blankj.utilcode.util.RegexUtils;

import org.greenrobot.eventbus.EventBus;

import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

import cn.gailvlun.gll.chatlib.bean.ChatMsgType;
import cn.gailvlun.gll.chatlib.bean.ChatReq;
import cn.gailvlun.gll.chatlib.bean.ChatRes;
import cn.gailvlun.gll.chatlib.bean.ChatResType;
import cn.gailvlun.gll.chatlib.bean.CrossMessage;
import cn.gailvlun.gll.chatlib.bean.CrossMessageType;
import cn.gailvlun.gll.chatlib.bean.SystemNotification;
import cn.gailvlun.gll.chatlib.db.ChatDB2;
import cn.gailvlun.gll.chatlib.event.CrossMatchSuccessEvent;
import cn.gailvlun.gll.chatlib.event.CrossMessageEvent;
import cn.gailvlun.gll.chatlib.event.CrossStatus;
import cn.gailvlun.gll.chatlib.event.CrossStatusEvent;
import cn.gailvlun.gll.chatlib.event.MatchSuccessEvent;
import cn.gailvlun.gll.chatlib.event.MessageEvent;
import cn.gailvlun.gll.chatlib.event.MessageSuccessEvent;
import cn.gailvlun.gll.chatlib.event.RoomCloseEvent;
import cn.gailvlun.gll.chatlib.event.RoomNameEvent;
import cn.gailvlun.gll.chatlib.message.Message;
import cn.gailvlun.gll.chatlib.message.MessageType;
import cn.gailvlun.gll.net.GsonUtil;
import cn.gailvlun.gll.net.HttpMethods;
import cn.gailvlun.gll.net.ListRes;
import cn.gailvlun.gll.net.Member;
import cn.gailvlun.gll.net.apartment.room.ApartmentTask;
import cn.gailvlun.gll.net.apartment.room.Room;
import cn.gailvlun.gll.net.apartment.task.TaskRecord;
import cn.gailvlun.gll.net.base.Profile;
import cn.gailvlun.gll.net.base.friend.FriendNotification;
import cn.gailvlun.gll.net.cross.CrossResult;
import cn.gailvlun.gll.net.cross.CrossRoomInfo;
import cn.gailvlun.gll.net.emotion.Comment;
import cn.gailvlun.gll.net.emotion.Emotion;
import cn.gailvlun.gll.net.hotel.InsomniaHotel;
import cn.gailvlun.gll.net.wish.MakeWish;
import cn.gailvlun.gll.util.AudioUtil;
import cn.gailvlun.gll.util.IsEmpty;
import cn.gailvlun.gll.util.LogUtil;
import cn.gailvlun.gll.util.ProfileUtil;
import cn.gailvlun.gll.util.RxUtil;
import cn.gailvlun.gll.util.TextUtilKt;
import io.reactivex.functions.Consumer;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;


public class ChatUtil {
    public static ChatRes getChatRes(String msg) {
        return GsonUtil.getGson().fromJson(msg, ChatRes.class);
    }

    public static void processMessage(ChatRes chatRes) {
        try {
            switch (chatRes.getMsg_type()) {
                case msg: {
                    processPrivateMessage(chatRes);
                    break;
                }
                case room_msg: {
                    processRoomMessage(chatRes);
                    break;
                }
                case notification: {
                    processNotification(chatRes);
                    break;
                }
                case room_notification: {
                    processRoomNotification(chatRes);
                    break;
                }
                case ark: {
                    processArk(chatRes);
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean isXRoomMsg(ChatRes chatRes) {
        if (chatRes.getMsg_type() == ChatResType.notification) {
            switch (chatRes.getData().getClazz()) {
                case "XRoomMatch":
                case "XRoom_BEFORE_OPEN":
                case "XRoom_FIRST_RIDDLE":
                case "XRoom_FIRST_RIDDLE_ANSWER":
                case "XRoom_FIRST_PUNISH":
                case "XRoom_HALF_TIME":
                case "XRoom_SECOND_RIDDLE":
                case "XRoom_SECOND_RIDDLE_ANSWER":
                case "XRoom_SECOND_PUNISH":
                case "XRoom_COMMENTING":
                case "XRoom_COMMENTED":
                case "XRoom_QUIT":
                    return true;
            }
        }
        return false;
    }

    public static String getXRoomId(ChatRes chatRes) {
        return chatRes.getData().getId();
    }

    private static boolean isSticker(String text) {
        return text.startsWith("ic_");
    }

    private static String getStickerLocalPath(String text) {
        // ic_not_happy1
        String dirName = getDirNameByNameNoExtension(text);
        return "file:///android_asset/sticker/" + dirName + "/" + text + ".jpg";
    }

    private static String getDirNameByNameNoExtension(String nameNoExtension) {
        String regex = "(?<=ic_).*?(?=\\d)";
        List<String> list = RegexUtils.getMatches(regex, nameNoExtension);
        if (list.size() == 0) {
            return "";
        }
        return list.get(0);
    }

    private static void processPrivateMessage(final ChatRes chatRes) {
        if (chatRes.getMsg().getClass_type().equals("x_room")) {
            final CrossMessage crossMessage = new CrossMessage();
            crossMessage.setCreated(chatRes.getMsg().getTimestamp());
            crossMessage.setOppositeId(chatRes.getFrom().getId());
            switch (chatRes.getMsg().getType()) {
                case txt: {
                    crossMessage.setType(CrossMessageType.TEXT);
                    crossMessage.setText(chatRes.getMsg().getPayload());
                    break;
                }
                case img: {
                    crossMessage.setType(CrossMessageType.IMAGE);
                    crossMessage.setImage(chatRes.getMsg().getPayload());
                    crossMessage.setWidth(chatRes.getMsg().getWidth());
                    crossMessage.setHeight(chatRes.getMsg().getHeight());
                    break;
                }
            }
            crossMessage.setSender(chatRes.getFrom());
            crossMessage.setCrossRoomInfo(ChatDB2.INSTANCE.getCrossRoomInfo());

            boolean isSaved = ChatDB2.INSTANCE.saveCrossMsg(crossMessage);

            if (!isSaved) {
                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {

                                EventBus.getDefault().post(new CrossMessageEvent(crossMessage.getId(), crossMessage.getOppositeId()));
                            }
                        });
            }
        } else {
            final Message msg = new Message();
            msg.setId(chatRes.getMsg().getId());
            switch (chatRes.getMsg().getType()) {
                case txt: {
                    if (isSticker(chatRes.getMsg().getPayload())) {
                        msg.setType(MessageType.sticker);
                        msg.setLocalImage(getStickerLocalPath(chatRes.getMsg().getPayload()));
                    } else {
                        msg.setType(MessageType.text);
                        msg.setText(chatRes.getMsg().getPayload());
                    }
                    break;
                }
                case img: {
                    msg.setType(MessageType.image);
                    msg.setImage(chatRes.getMsg().getPayload());
                    msg.setWidth(chatRes.getMsg().getWidth());
                    msg.setHeight(chatRes.getMsg().getHeight());
                    break;
                }
                case audio: {
                    msg.setType(MessageType.walkieTalkie);
                    msg.setWalkieTalkie(chatRes.getMsg().getPayload());
                    msg.setWtSecond((int) (AudioUtil.getDuration(msg.getWalkieTalkie()) / 1000));
                    break;
                }
            }
            msg.setUnread(true);
            msg.setCreated(chatRes.getMsg().getTimestamp());
            msg.setSender(chatRes.getFrom());
            msg.setDialogId("user:" + chatRes.getFrom().getId());

            boolean isSaved = ChatDB2.INSTANCE.saveMsg(msg);

            if (!isSaved) {
                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                            }
                        });
            }
        }
    }

    private static void processRoomMessage(final ChatRes chatRes) {
        if (chatRes.getData() != null) {

            switch (chatRes.getData().getClazz()) {
                case "RoomTask": {
                    ApartmentTask task = GsonUtil.getGson()
                            .fromJson(
                                    GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                                    ApartmentTask.class);
                    ChatDB2.INSTANCE.save(task);

                    final Message msg = Message.text(task.getDesc(), new Date(), chatRes.getFrom(), "room:" + task.getRoom());
                    msg.setRoom(ChatDB2.INSTANCE.searchRoomById(task.getRoom()));
                    ChatDB2.INSTANCE.save(msg);

                    RxUtil.timer(100, TimeUnit.MILLISECONDS)
                            .subscribe(new Consumer<Long>() {
                                @Override
                                public void accept(Long aLong) throws Exception {
                                    EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                                }
                            });
                    break;
                }
                case "RoomTaskRecord": {

                    TaskRecord addTaskRecord = GsonUtil.getGson()
                            .fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                                    TaskRecord.class);
                    final Message msg = Message.checkIn(addTaskRecord, new Date(), chatRes.getFrom(), "room:" + addTaskRecord.getMember().getRoom());
                    msg.setRoom(ChatDB2.INSTANCE.searchRoomById(addTaskRecord.getMember().getRoom()));
                    ChatDB2.INSTANCE.save(msg);
                    LogUtil.d("Get a room task record: " + msg.getId());

                    RxUtil.timer(100, TimeUnit.MILLISECONDS)
                            .subscribe(new Consumer<Long>() {
                                @Override
                                public void accept(Long aLong) throws Exception {
                                    EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                                }
                            });
                    break;
                }
            }
        } else {
            final Message msg = new Message();
            switch (chatRes.getMsg().getType()) {
                case txt: {
//                    msg.setType(MessageType.text);
//                    msg.setText(chatRes.getMsg().getPayload());
                    if (isSticker(chatRes.getMsg().getPayload())) {
                        msg.setType(MessageType.sticker);
                        msg.setLocalImage(getStickerLocalPath(chatRes.getMsg().getPayload()));
                    } else {
                        msg.setType(MessageType.text);
                        msg.setText(chatRes.getMsg().getPayload());
                    }
                    break;
                }
                case img: {
                    msg.setType(MessageType.image);
                    msg.setImage(chatRes.getMsg().getPayload());
                    msg.setWidth(chatRes.getMsg().getWidth());
                    msg.setHeight(chatRes.getMsg().getHeight());
                    break;
                }
                case audio: {
                    msg.setType(MessageType.walkieTalkie);
                    msg.setWalkieTalkie(chatRes.getMsg().getPayload());
                    msg.setWtSecond((int) (AudioUtil.getDuration(msg.getWalkieTalkie()) / 1000));
                    break;
                }
            }
            msg.setRoom(ChatDB2.INSTANCE.searchRoomById(chatRes.getRoom()));
            msg.setUnread(true);
            msg.setCreated(chatRes.getMsg().getTimestamp());
            msg.setSender(chatRes.getFrom());
            msg.setDialogId("room:" + chatRes.getRoom());
            msg.setNickName(chatRes.getNickname());
            msg.setAtAll(chatRes.getMsg().isAtAll());
            if (!IsEmpty.list(chatRes.getMsg().getAtWhomList())) {
                msg.setAtWhomList(chatRes.getMsg().getAtWhomList());
            }

            LogUtil.d("发送: id: " + msg.getId() + ", dialogId: " + msg.getDialogId());

            boolean isSaved = ChatDB2.INSTANCE.saveMsg(msg);
            if (!isSaved) {
                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                            }
                        });
            }
        }
    }

    private static void processRoomNotification(ChatRes chatRes) {

        int roomId = chatRes.getRoom();
        String text = chatRes.getMsg().getText();
        if ("你已被禁言".equals(text)) {

            ChatDB2.INSTANCE.block(roomId);
        } else if ("你已被取消禁言".equals(text)) {

            ChatDB2.INSTANCE.unblock(roomId);
        }
    }

    private static void processArk(ChatRes chatRes) {
        final String msgId = chatRes.getId();

        // 修改状态为成功
        final String dialogId = ChatDB2.INSTANCE.saveAsSuccess(chatRes.getId());
        LogUtil.d("状态已修改: id:" + msgId + ", dialogId: " + dialogId);

        RxUtil.timer(100, TimeUnit.MILLISECONDS)
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        EventBus.getDefault().post(new MessageSuccessEvent(msgId, dialogId));
                    }
                });
    }

    private static void processNotification(final ChatRes chatRes) {
        switch (chatRes.getData().getClazz()) {
            case "FriendInvite": {
                FriendNotification friendNotification =
                        GsonUtil.getGson().fromJson(
                                GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                                FriendNotification.class);
                if (friendNotification.getStatus() == 1) {
                    break;
                }

                ChatDB2.INSTANCE.saveFriendNoti(friendNotification);
                break;
            }
            case "FriendAccess": {


                break;
            }
            case "Room": {

                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.roomOpen);
                noti.setRoom(room);
                noti.setFrom(chatRes.getFrom());
                noti.setCreated(room.getStart_datetime());
                noti.setText(chatRes.getMsg().getPayload());

                final Message msg = Message.text(chatRes.getMsg().getPayload(), room.getStart_datetime(), chatRes.getFrom(), "room:" + room.getId());
                msg.setRoom(room);
                ChatDB2.INSTANCE.saveRoom(room);
                ChatDB2.INSTANCE.saveNoti(noti);
                ChatDB2.INSTANCE.save(msg);

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                            }
                        });
                break;
            }
            case "ChatGroup_Update": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                ChatDB2.INSTANCE.save(room);

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new RoomNameEvent(room.getName()));
                            }
                        });
                break;
            }
            case "ChatGroup": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                if (room.getOwner().getId() == ProfileUtil.getUserId()) {
                    break;
                }

                HttpMethods.getGroupService()
                        .getGroupMemberSync(room.getId())
                        .enqueue(new Callback<ListRes<Member>>() {
                            @Override
                            public void onResponse(Call<ListRes<Member>> call, Response<ListRes<Member>> response) {
                                room.setName(TextUtilKt.join("、", response.body().getResults(), true));
                                ChatDB2.INSTANCE.saveRoom(room);


                                StringBuilder sb = new StringBuilder().append(room.getOwner().getName())
                                        .append("邀请\"")
                                        .append(TextUtilKt.join("、", response.body().getResults(), false))
                                        .append("\"加入了群聊");
                                final Message msg = new Message();
                                msg.setType(MessageType.initInfo);
                                msg.setText(sb.toString());
                                msg.setCreated(room.getCreated());

                                msg.setDialogId("room:" + room.getId());

                                ChatDB2.INSTANCE.save(msg);

                                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                                        .subscribe(new Consumer<Long>() {
                                            @Override
                                            public void accept(Long aLong) throws Exception {
                                                EventBus.getDefault().post(new MessageEvent(msg.getId(), msg.getDialogId()));
                                            }
                                        });
                            }

                            @Override
                            public void onFailure(Call<ListRes<Member>> call, Throwable t) {

                            }
                        });
                break;
            }
            case "RoomBeforeStarting": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), Room.class);

                SystemNotification noti = new SystemNotification();


                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "RoomBeforeClosing": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.roomStartSign);
                noti.setRoom(room);
                noti.setFrom(chatRes.getFrom());
                noti.setCreated(new Date());
                noti.setText(chatRes.getMsg().getPayload());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "RoomAbortion": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.roomAbortion);
                noti.setRoom(room);
                noti.setFrom(chatRes.getFrom());
                noti.setCreated(new Date());
                noti.setText(chatRes.getMsg().getPayload());

                ChatDB2.INSTANCE.saveNoti(noti);
                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new RoomCloseEvent(room.getId()));
                            }
                        });
                break;
            }
            case "schedule": {

                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);
                ChatDB2.INSTANCE.deleteAllRoomMessage(room.getId());

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new RoomCloseEvent(room.getId()));
                            }
                        });

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.roomClosed);
                noti.setRoom(room);
                noti.setFrom(chatRes.getFrom());
                noti.setCreated(room.getClose_datetime());
                noti.setText(chatRes.getMsg().getPayload());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "RoomInvite": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                final Message roomInviteMsg = Message.invite(room, new Date(), chatRes.getFrom(),
                        "user:" + chatRes.getFrom().getId());

                ChatDB2.INSTANCE.save(roomInviteMsg);

                RxUtil.timer(100, TimeUnit.SECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MessageEvent(roomInviteMsg.getId(), roomInviteMsg.getDialogId()));
                            }
                        });
                break;
            }
            case "Member": {

                final Member member = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), Member.class
                );

                ChatDB2.INSTANCE.save(member);
                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MatchSuccessEvent(member.getId(), member.getRoom()));
                            }
                        });
                break;
            }
            case "EmoNoticeHeart": {
                final Emotion emotion = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), Emotion.class
                );

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.emotionHeart);
                noti.setEmotion(emotion);
                noti.setCreated(chatRes.getDatetime());
                noti.setFrom(chatRes.getFrom());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "EmoNoticeComment": {
                final Emotion emotion = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), Emotion.class
                );
                final Comment comment = chatRes.getData().getComment();

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.emotionComment);
                noti.setEmotion(emotion);
                noti.setComment(comment);
                noti.setCreated(new Date());
                noti.setFrom(chatRes.getFrom());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "WishNoticeAccepted": {
                MakeWish wish = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), MakeWish.class
                );

                Profile accepter = wish.getAccepter();
                Profile owner = wish.getOwner();


                final Message myWishMsg = Message.text("嗨，很高兴认识你哦！\n下面是我许的愿望哦，希望你能帮我完成:\n" + wish.getText(), wish.getAccepted_datetime(), owner, "user:" + accepter.getId());

                long time = wish.getAccepted_datetime().getTime() + 100;
                final Message resMsg = Message.text("久等了，我是你的救世主~ \n我来帮你实现愿望啦，请多多指教哦！", new Date(time), accepter, "user:" + accepter.getId());
                ChatDB2.INSTANCE.save(myWishMsg);
                ChatDB2.INSTANCE.save(resMsg);

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) throws Exception {
                                EventBus.getDefault().post(new MessageEvent(myWishMsg.getId(), myWishMsg.getDialogId()));
                                EventBus.getDefault().post(new MessageEvent(resMsg.getId(), resMsg.getDialogId()));
                            }
                        });
                break;

            }
            case "WishNoticeHow": {
                final MakeWish makeWish = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), MakeWish.class
                );

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.wishDeadLine);
                noti.setWish(makeWish);
                noti.setCreated(new Date());
                noti.setFrom(chatRes.getFrom());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "HotelNoticeComment": {
                final InsomniaHotel insomniaHotel = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), InsomniaHotel.class
                );
                final Comment comment = chatRes.getData().getComment();

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.hotelComment);
                noti.setHotelInsomnia(insomniaHotel);
                noti.setComment(comment);
                noti.setCreated(new Date());
                noti.setFrom(chatRes.getFrom());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }


            case "HotelNoticeHeart": {
                final InsomniaHotel insomniaHotel = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), InsomniaHotel.class
                );

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.hotelHeart);
                noti.setHotelInsomnia(insomniaHotel);
                noti.setCreated(new Date());
                noti.setFrom(chatRes.getFrom());

                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "RoomCensorResult": {
                final Room room = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()),
                        Room.class);

                SystemNotification noti = new SystemNotification();
                noti.setType(NotificationType.roomReviewed);
                noti.setRoom(room);
                noti.setFrom(chatRes.getFrom());
                noti.setCreated(room.getCensor_feedback_time());
                noti.setText(chatRes.getMsg().getPayload());

                ChatDB2.INSTANCE.saveRoom(room);
                ChatDB2.INSTANCE.saveNoti(noti);
                break;
            }
            case "XRoomMatch": {
                CrossRoomInfo info = GsonUtil.getGson().fromJson(GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), CrossRoomInfo.class);
                ChatDB2.INSTANCE.save(info);
                EventBus.getDefault().post(new CrossMatchSuccessEvent(info.getId()));
                break;
            }
            case "XRoom_BEFORE_OPEN": {
                CrossResult crossResult = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), CrossResult.class
                );
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.BEFORE_OPEN, chatRes.getFrom().getId(), crossResult.getId()));
                break;
            }
            case "XRoom_FIRST_RIDDLE": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.FIRST_RIDDLE));
                break;
            }
            case "XRoom_FIRST_RIDDLE_ANSWER": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.FIRST_RIDDLE_ANSWER));
                break;
            }
            case "XRoom_FIRST_PUNISH": {
                final CrossResult crossResult = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), CrossResult.class
                );

                ChatDB2.INSTANCE.saveFirstRiddleAnswer(crossResult);

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) {
                                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.FIRST_PUNISH));
                            }
                        });
                break;
            }
            case "XRoom_HALF_TIME": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.HALF_TIME));
                break;
            }
            case "XRoom_SECOND_RIDDLE": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.SECOND_RIDDLE));
                break;
            }
            case "XRoom_SECOND_RIDDLE_ANSWER": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.SECOND_RIDDLE_ANSWER));
                break;
            }
            case "XRoom_SECOND_PUNISH": {
                final CrossResult crossResult = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), CrossResult.class
                );

                ChatDB2.INSTANCE.saveSecondRiddleAnswer(crossResult);

                RxUtil.timer(100, TimeUnit.MILLISECONDS)
                        .subscribe(new Consumer<Long>() {
                            @Override
                            public void accept(Long aLong) {
                                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.SECOND_PUNISH));
                            }
                        });
                break;
            }
            case "XRoom_COMMENTING": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.COMMENTING));
                break;
            }
            case "XRoom_COMMENTED": {
                final CrossResult crossResult = GsonUtil.getGson().fromJson(
                        GsonUtil.getGson().toJsonTree(chatRes.getData().getObj()), CrossResult.class
                );

                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.COMMENTED, crossResult.getOppositeTagForMe()));
                break;
            }
            case "XRoom_QUIT": {
                EventBus.getDefault().post(new CrossStatusEvent(CrossStatus.OTHER_EXIT));
                break;
            }
        }
    }

    public static String sendMessage(final Message msg) {
        ChatReq chatReq = ChatReq.create(msg.getDialogId());
        chatReq.setId(msg.getId());
        if (!IsEmpty.list(msg.getAtWhomList())) {
            chatReq.setAtWhomList(msg.getAtWhomList());
        }
        if (msg.isAtAll()) {
            chatReq.setAtAll("True");
        } else {
            chatReq.setAtAll(null);

        }
        switch (msg.getType()) {
            case text: {
                chatReq.setType(ChatMsgType.txt);
                chatReq.setPayload(msg.getText());
                break;
            }
            case image: {
                chatReq.setType(ChatMsgType.img);
                chatReq.setPayload(msg.getImage());
                chatReq.setWidth(msg.getWidth());
                chatReq.setHeight(msg.getHeight());
                break;
            }
            case walkieTalkie: {
                chatReq.setType(ChatMsgType.audio);
                chatReq.setPayload(msg.getWalkieTalkie());
                break;
            }
            case sticker: {
                chatReq.setType(ChatMsgType.txt);
                chatReq.setPayload(FileUtils.getFileNameNoExtension(msg.getLocalImage()));
            }
        }
        chatReq.setSeq(System.currentTimeMillis() / 1000);
        String messageJson = GsonUtil.getGson().toJson(chatReq);
        LogUtil.d(messageJson);
        return messageJson;
    }

    public static String sendCrossMessage(final CrossMessage msg) {
        ChatReq chatReq = ChatReq.create("user:" + msg.getOppositeId());
        chatReq.setId(msg.getId());
        chatReq.setClass_type("x_room");
        switch (msg.getType()) {
            case TEXT: {
                chatReq.setType(ChatMsgType.txt);
                chatReq.setPayload(msg.getText());
                break;
            }
            case IMAGE: {
                chatReq.setType(ChatMsgType.img);
                chatReq.setPayload(msg.getImage());
                chatReq.setWidth(msg.getWidth());
                chatReq.setHeight(msg.getHeight());
                break;
            }
        }
        chatReq.setSeq(System.currentTimeMillis() / 1000);
        String messageJson = GsonUtil.getGson().toJson(chatReq);
        LogUtil.d(messageJson);
        return messageJson;
    }
}
